/*
11、柠檬水找零
2022-10-13
link:860-https://leetcode.cn/problems/lemonade-change/
question:
	在柠檬水摊上，每一杯柠檬水的售价为 5 美元。顾客排队购买你的产品，（按账单 bills 支付的顺序）一次购买一杯。
每位顾客只买一杯柠檬水，然后向你付 5 美元、10 美元或 20 美元。你必须给每个顾客正确找零，也就是说净交易是每位顾客向你支付 5 美元。
注意，一开始你手头没有任何零钱。
如果你能给每位顾客正确找零，返回 true ，否则返回 false 。
answer:
	维护三种金额的数量，5，10和20。
有如下三种情况：
情况一：账单是5，直接收下。
情况二：账单是10，消耗一个5，增加一个10
情况三：账单是20，优先消耗一个10和一个5，如果不够，再消耗三个5
此时发现 情况一，情况二，都是固定策略，都不用我们来做分析了，而唯一不确定的其实在情况三。
因为美元10只能给账单20找零，而美元5可以给账单10和账单20找零，美元5更万能！
所以局部最优：遇到账单20，优先消耗美元10，完成本次找零。全局最优：完成全部账单的找零。
局部最优可以推出全局最优，并找不出反例，就试试贪心算法！
*/

// 注意这里5，10，20已经排好序了
func lemonadeChange(bills []int) bool {
	hash := make(map[int]int, 3)
	for i := 0; i < len(bills); i++ {
		if bills[i] == 5 {
			hash[5]++
		} else if bills[i] == 10 {
			if hash[5] <= 0 {
				return false
			}
			hash[10]++
			hash[5]--
		} else if bills[i] == 20 {
			if hash[10] > 0 && hash[5] > 0 { // 这里有些局部最优考虑了，一定要先消费10的
				hash[10]--
				hash[5]--
			} else if hash[5] >= 3 {
				hash[5] -= 3
			} else {
				return false
			}
		}
	}
	return true
}